// 设置全局错误处理器
process.on('uncaughtException', (error) => {
    console.error('未捕获的异常:', error);
    console.error('错误堆栈:', error.stack);
});

process.on('unhandledRejection', (reason, promise) => {
    console.error('未处理的Promise拒绝:', reason);
    if (reason instanceof Error) {
        console.error('错误堆栈:', reason.stack);
    }
});

const path = require('path');
const { customRequire } = require('./utils.js');

// 导入外部模块
console.log('正在导入playwright模块...');
const { chromium } = customRequire('playwright');
console.log('正在导入fs模块...');
const fs = require('fs');
console.log('正在导入winston模块...');
const winston = customRequire('winston');

// 导入本地模块（相对路径不变）
const { LoginPage } = require('./login_page.js');
const { FirstPage } = require('./first_page.js');
const { ReportListPage } = require('./report_list_page.js');
const { sendMonitoringData } = require("./user-data.js")
const manifest = require('./manifest.json');

// 检查模块缓存情况
console.log('\n===== 模块缓存检查 =====');
try {
    // 获取模块缓存对象
    const moduleCache = require.cache;
    if (!moduleCache) {
        console.log('无法获取模块缓存');
    } else {
        // 统计缓存的模块数量
        const cacheKeys = Object.keys(moduleCache);
        console.log(`缓存的模块总数: ${cacheKeys.length}`);
        
        // 按类型分类模块
        const moduleTypes = {
            node_modules: [],
            local: [],
            system: [],
            other: []
        };
        
        cacheKeys.forEach(key => {
            if (key.includes('node_modules')) {
                moduleTypes.node_modules.push(key);
            } else if (key.includes('batch-reject')) {
                moduleTypes.local.push(key);
            } else if (key.startsWith('node:') || key.includes('internal')) {
                moduleTypes.system.push(key);
            } else {
                moduleTypes.other.push(key);
            }
        });
        
        // 打印分类统计
        console.log(`系统模块: ${moduleTypes.system.length}`);
        console.log(`node_modules模块: ${moduleTypes.node_modules.length}`);
        console.log(`本地模块: ${moduleTypes.local.length}`);
        console.log(`其他模块: ${moduleTypes.other.length}`);
        
        // 打印本地模块详情
        console.log('\n本地模块缓存详情:');
        moduleTypes.local.forEach(modulePath => {
            const mod = moduleCache[modulePath];
            console.log(`  - ${modulePath}`);
            console.log(`    加载状态: ${mod.loaded ? '已加载' : '未加载'}`);
            if (mod.children && mod.children.length > 0) {
                console.log(`    依赖模块数: ${mod.children.length}`);
            }
        });
        
        // 检查关键第三方模块
        const keyModules = ['playwright', '@playwright/test', 'winston', 'axios', 'electron'];
        console.log('\n关键第三方模块缓存状态:');
        keyModules.forEach(moduleName => {
            try {
                customRequire(moduleName);
                console.log(`  - ${moduleName}: 已成功加载`);
            } catch (e) {
                console.log(`  - ${moduleName}: 加载失败 (${e.message})`);
            }
        });
    }
} catch (e) {
    console.log(`模块缓存检查失败: ${e.message}`);
}
console.log('===== 模块缓存检查结束 =====\n');

// 初始化日志库
const logger = winston.createLogger({
    level: 'info',
    format: winston.format.json(),
    transports: [
        new winston.transports.File({ filename: 'log/batch_reject_error.log', level: 'error' }),
        new winston.transports.File({ filename: 'log/batch_reject_combined.log' }),
    ],
});

async function openBrowser(url, headless) {
    try {
        // 根据headless参数设置浏览器模式
        // 当headless为true时（显示操作步骤），设置为false（显示浏览器）
        // 当headless为false时（隐藏操作步骤），设置为true（使用无头模式）
        const headlessValue = headless ? false : true;
        
        const browser = await chromium.launch({
            headless: headlessValue,
            args: ['--start-maximized', '--disable-features=IsolateOrigins,site-per-process'],
            executablePath: 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
        });
        if (!browser) {
            throw new Error("Playwright browser instance hasn't been initialized yet.");
        }
        const context = await browser.newContext({ viewport: null }); // 创建新的浏览器上下文
        const page = await context.newPage(); // 在上下文中创建新的页面

        const login = new LoginPage(page);
        await login.GPOOpen(url);
        await login.singleSignOn();
        const first = new FirstPage(page);
        first.reportListEntry();
        return { browser, page, context };
    } catch (error) {
        logger.error(`Error in openBrowser: ${error.stack || error}`, 'error');
        console.error(`Error in openBrowser: ${error.stack || error}`);
        throw error;
    }
}

async function batchReject(browser, page, reportNumbers, userSettings) {
    // 创建结果数组，用于存储每个报告的处理结果
    const results = [];
    
    // 创建一个Map来跟踪已处理的报告号
    const processedReportNos = new Map();
    
    try {
        let report_list_page = new ReportListPage(page);
        // await report_list_page.search_order_no_batch(orderNumbers);
        // 打印 report_list_page 对象
        // console.log('report_list_page:', report_list_page);
        await report_list_page.search_report_no_batch(reportNumbers);
        const reportListBodyXpath = `//*[@id="pane-myReportTab"]/div/div/div[2]/div[3]/table/tbody`;
        await page.waitForSelector(reportListBodyXpath);
        const trCount = await page.locator(`${reportListBodyXpath}/tr`).count();
        logger.info(`共查询到 ${trCount} 条记录`, 'info');
        console.log('trCount:', trCount);
        for (let trNo = 1; trNo <= trCount; trNo++) {
            try{
                const orderNoXpath = `${reportListBodyXpath}/tr[${trNo}]/td[2]`;
                const reportNoXpath = `${reportListBodyXpath}/tr[${trNo}]/td[3]`;
                const reportStatusXpath = `${reportListBodyXpath}/tr[${trNo}]/td[5]`;
                let orderNoContent = await page.locator(orderNoXpath).textContent();
                logger.info(`正在处理order: ${orderNoContent}`);
                console.log(`正在处理order: ${orderNoContent}`);
                let reportNoContent = await page.locator(reportNoXpath).textContent();
                let reportStatusContent = await page.locator(reportStatusXpath).textContent();
                
                // 标记该报告号已处理
                if (reportNoContent) {
                    reportNoContent = reportNoContent.replace(/\s+/g, '');
                    processedReportNos.set(reportNoContent, true);
                }

                if (reportStatusContent && orderNoContent && reportNoContent) {
                    orderNoContent = orderNoContent.replace(/\s+/g, '');
                    reportNoContent = reportNoContent.replace(/\s+/g, '');
                    reportStatusContent = reportStatusContent.replace(/\s+/g, '');
                    logger.info(`Order No: ${orderNoContent} Report No: ${reportNoContent} Report Status: ${reportStatusContent}`, 'info');
                    console.log(`Order No: ${orderNoContent} Report No: ${reportNoContent} Report Status: ${reportStatusContent}`);
                    // 提取 orderNo 的最后两位英文字母
                    const orderNoSuffix = orderNoContent.slice(-2);
                    if (/^[a-zA-Z]{2}$/.test(orderNoSuffix)) {
                        // 去掉 orderNo 的最后两位英文字母
                        const orderNoWithoutSuffix = orderNoContent.slice(0, -2);

                        // 检查 reportNo 是否符合规则
                        const expectedPattern = new RegExp(`^${orderNoWithoutSuffix}\\d{2}${orderNoSuffix}$`);

                        // 创建结果对象，无论是否满足条件都会记录
                        let rejectResult = {
                            orderNo: orderNoContent,
                            reportNo: reportNoContent,
                            status: reportStatusContent,
                            success: false,
                            message: ''
                        };
                        
                        if (expectedPattern.test(reportNoContent) && reportStatusContent === "Approved") {
                            logger.info(`reportNo matches the expected pattern: ${reportNoContent}`, 'info');
                            console.log(`reportNo matches the expected pattern: ${reportNoContent}`);
                            
                            try {
                                await report_list_page.click_action_button(trNo.toString());
                                // const rejectButtonSelector = 'button.el-button.el-button--default.el-button--text span:text("Reject")';
                                const rejectButtonSelector = 'button.el-button.el-button--default.el-button--text:has-text("Reject")';
                                const rejectButtons = await page.locator(rejectButtonSelector).all();
                                if (rejectButtons.length > 0) {
                                    const lastRejectButton = rejectButtons[rejectButtons.length - 1];
                                    
                                    try {
                                        // 等待按钮可见并可点击
                                        await lastRejectButton.waitFor({state: 'visible', timeout: 60000});
                                        // 使用force: true选项点击
                                        await lastRejectButton.click({force: true, timeout: 60000});
                                        logger.info(`${orderNoContent} Reject button clicked`, 'info');
                                        console.log(`${orderNoContent} Reject button clicked`);
                                    } catch (clickError) {
                                        logger.info(`尝试备用方法点击Reject按钮: ${clickError.message}`, 'info');
                                        console.log(`尝试备用方法点击Reject按钮: ${clickError.message}`);
                                        
                                        // 尝试使用JavaScript直接点击
                                        await page.evaluate((selector) => {
                                            const buttons = Array.from(document.querySelectorAll(selector));
                                            if (buttons.length > 0) {
                                                const lastButton = buttons[buttons.length - 1];
                                                lastButton.click();
                                            }
                                        }, rejectButtonSelector);
                                    }
                                    
                                    // 等待 Reject Dialog 出现，使用更长的超时时间
                                    const reportRejectDialog = '//div[@aria-label="Report Reject"][@class="el-dialog"]';
                                    await page.waitForSelector(reportRejectDialog, { state: 'visible', timeout: 60000 });
                                    await page.waitForTimeout(1000); // 额外等待确保对话框完全加载
                                    
                                    try {
                                        // 选择 Reject Reason Type 下拉框中的 '测试结果错误' 选项
                                        const dropdownSelector = '//div[@aria-label="Report Reject"][@class="el-dialog"]/div[2]/div/div/form/div[2]/div/div';
                                        await page.waitForSelector(dropdownSelector, { state: 'visible', timeout: 60000 });
                                        await page.locator(dropdownSelector).click({ force: true, timeout: 60000 }); // 打开下拉框
                                        
                                        // 等待下拉选项出现
                                        await page.waitForTimeout(1000);
                                        const optionSelector = 'li.el-select-dropdown__item span:has-text("测试结果错误")';
                                        await page.waitForSelector(optionSelector, { state: 'visible', timeout: 60000 });
                                        await page.locator(optionSelector).click({ force: true, timeout: 60000 }); // 选择 '测试结果错误'
                                    } catch (dialogError) {
                                        logger.info(`尝试备用方法选择下拉选项: ${dialogError.message}`, 'info');
                                        console.log(`尝试备用方法选择下拉选项: ${dialogError.message}`);
                                        
                                        // 使用JavaScript直接选择选项
                                        await page.evaluate(() => {
                                            // 先点击下拉框
                                            const dropdown = document.evaluate('//div[@aria-label="Report Reject"][@class="el-dialog"]/div[2]/div/div/form/div[2]/div/div', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                                            if (dropdown) dropdown.click();
                                            
                                            // 等待下拉选项出现并选择
                                            setTimeout(() => {
                                                const options = Array.from(document.querySelectorAll('li.el-select-dropdown__item span'));
                                                const target = options.find(el => el.textContent.includes('测试结果错误'));
                                                if (target) target.click();
                                            }, 500);
                                        });
                                        await page.waitForTimeout(1000);
                                    }
                                    
                                    // 点击 Submit 按钮
                                    try {
                                        const submitButton = '//div[@aria-label="Report Reject"][@class="el-dialog"]/div[3]/div/button[2]';
                                        await page.waitForSelector(submitButton, { state: 'visible', timeout: 60000 });
                                        await page.locator(submitButton).click({ force: true, timeout: 60000 });
                                    } catch (submitError) {
                                        logger.info(`尝试备用方法点击Submit按钮: ${submitError.message}`, 'info');
                                        console.log(`尝试备用方法点击Submit按钮: ${submitError.message}`);
                                        
                                        // 使用JavaScript直接点击Submit按钮
                                        await page.evaluate(() => {
                                            const submitBtn = document.evaluate('//div[@aria-label="Report Reject"][@class="el-dialog"]/div[3]/div/button[2]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
                                            if (submitBtn) submitBtn.click();
                                        });
                                    }
                                    
                                    // 标记为成功
                                    rejectResult.success = true;
                                    rejectResult.message = 'Reject 操作成功';
                                    
                                    const monitoringData = {
                                        user_name: userSettings.email?.split('@')[0] || 'unknown',
                                        user_location: userSettings.site || 'unknown',
                                        rpa_id: "136",
                                        rpa_name: "report_batch_reject",
                                        rpa_version: manifest.version,
                                        occurrence: new Date().toLocaleString('en-US', {
                                            weekday: 'short',
                                            day: '2-digit',
                                            month: 'short',
                                            year: 'numeric',
                                            hour: '2-digit',
                                            minute: '2-digit',
                                            second: '2-digit',
                                            hour12: false
                                        }),
                                        info: "GPO Report批量reject.",
                                        extra: reportNoContent
                                    };
                                    // 发送监控数据并记录详细日志
                                    console.log('准备发送的监控数据：', monitoringData);
                                    const monitoringResult = await sendMonitoringData([monitoringData]);
                                    
                                    // 将监控数据发送状态添加到结果对象中
                                    if (!monitoringResult.success) {
                                        rejectResult.monitoringStatus = false;
                                        rejectResult.monitoringMessage = monitoringResult.message;
                                        console.log(`监控数据发送失败 - 报告号: ${reportNoContent}, 错误信息: ${monitoringResult.message}`);
                                    } else {
                                        rejectResult.monitoringStatus = true;
                                        rejectResult.monitoringMessage = monitoringResult.message;
                                        console.log(`监控数据发送成功 - 报告号: ${reportNoContent}`);
                                    }
                                    
                                    // 记录当前处理结果的详细信息
                                    console.log('当前报告处理结果：', {
                                        reportNo: reportNoContent,
                                        success: rejectResult.success,
                                        message: rejectResult.message,
                                        monitoringStatus: rejectResult.monitoringStatus,
                                        monitoringMessage: rejectResult.monitoringMessage
                                    });
                                } else {
                                    rejectResult.message = 'No Reject buttons found';
                                    logger.error(`${orderNoContent} No Reject buttons found`, 'error');
                                    console.error(`${orderNoContent} No Reject buttons found`);
                                }
                            } catch (error) {
                                rejectResult.message = `Reject 操作失败: ${error.message}`;
                                logger.error(`${orderNoContent} Reject 操作失败: ${error.message}`, 'error');
                                console.error(`${orderNoContent} Reject 操作失败: ${error.message}`);
                            }
                        } else if (!expectedPattern.test(reportNoContent)) {
                            rejectResult.message = `报告号不匹配预期模式，预期模式: ${orderNoWithoutSuffix}\\d{2}${orderNoSuffix}`;
                            logger.info(`reportNo does not match the expected pattern. Expected pattern: ${orderNoWithoutSuffix}\\d{2}${orderNoSuffix}, Original: ${reportNoContent}`, 'info');
                        } else if (reportStatusContent !== "Approved") {
                            rejectResult.message = `报告状态不是 Approved，当前状态: ${reportStatusContent}`;
                            logger.info(`Report Status is not Approved: ${reportStatusContent}`, 'info');
                        }
                        
                        // 添加结果到数组，无论是否满足条件
                        results.push(rejectResult);
                    }
                }
            } catch (error) {
                logger.error(`处理第 ${trNo} 条记录时出错: ${error.stack || error}`);
                console.error(`处理第 ${trNo} 条记录时出错: ${error.stack || error}`);
            }
        }
    } catch (error) {
        logger.error(`Web process failed: ${error.stack || error}`);
        console.error(`Web process failed: ${error.stack || error}`);
    } finally {
        // 检查是否有未处理的报告号
        for (const reportNo of reportNumbers) {
            const trimmedReportNo = reportNo.trim();
            if (trimmedReportNo && !processedReportNos.has(trimmedReportNo)) {
                // 为未处理的报告号创建结果记录
                const result = {
                    orderNo: '-',
                    reportNo: trimmedReportNo,
                    status: '-',
                    success: false,
                    message: '未找到对应的报告记录'
                };
                results.push(result);
                logger.info(`未找到报告号 ${trimmedReportNo} 对应的记录`, 'info');
                console.log(`未找到报告号 ${trimmedReportNo} 对应的记录`);
            }
        }
        
        if (browser) {
            await browser.close();
        }
    }
    return results;
}

module.exports = async (url, headless, reportNumbers, userSettings) => {
    try {
        // 调用 openBrowser 方法并等待其执行完成
        const { browser, page, context } = await openBrowser(url, headless);
        
        // 调用 batchReject 方法并获取结果
        const results = await batchReject(browser, page, reportNumbers, userSettings);
        
        // 确保monitoringStatus和monitoringMessage字段被正确传递
        const processedResults = results.map(result => {
            const processedResult = {
                orderNo: result.orderNo,
                reportNo: result.reportNo,
                status: result.status,
                success: result.success,
                message: result.message
            };
            
            // 确保监控状态字段被正确传递
            if (result.hasOwnProperty('monitoringStatus')) {
                processedResult.monitoringStatus = result.monitoringStatus;
            }
            if (result.hasOwnProperty('monitoringMessage')) {
                processedResult.monitoringMessage = result.monitoringMessage;
            }
            
            return processedResult;
        });
        
        // 返回处理结果
        return processedResults;
    } catch (error) {
        logger.error(`Main process failed: ${error.stack || error}`);
        console.error(`Main process failed: ${error.stack || error}`);
        throw error;
    }
};